﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Reflection;

namespace POSPlus.PrintManager
{
	public class StringValueAttribute : Attribute
	{
		private string _value;

		public string Value { get { return _value; } }

		public StringValueAttribute(string value)
		{
			_value = value;
		}
	}

	public class ShortStringAttribute : Attribute
	{
		private string _value;

		public string Value { get { return _value; } }

		public ShortStringAttribute(string value)
		{
			_value = value;
		}
	}



	public class ShortStringEnum
	{
		#region Instance Implementation
		private Type _enumType;
		private static Dictionary<Enum, ShortStringAttribute> _stringValues = new Dictionary<Enum, ShortStringAttribute>();

		public ShortStringEnum(Type enumType)
		{
			if (!enumType.IsEnum)
				throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}", enumType.ToString()));

			_enumType = enumType;
		}

		public string GetStringValue(string valueName)
		{
			Enum enumType;
			string stringValue = null;

			try
			{
				enumType = (Enum)Enum.Parse(_enumType, valueName);
				stringValue = GetStringValue(enumType);
			}
			catch (Exception) { }

			return stringValue;
		}

		public Array GetStringValues()
		{
			ArrayList values = new ArrayList();
			foreach (FieldInfo fi in _enumType.GetFields())
			{
				ShortStringAttribute[] attrs =
					(ShortStringAttribute[])fi.GetCustomAttributes(typeof(ShortStringAttribute), false);

				if (attrs.Length > 0)
					values.Add(attrs[0].Value);
			}

			return values.ToArray();
		}

		public IList GetListValues()
		{
			Type underlyingType = Enum.GetUnderlyingType(_enumType);
			ArrayList values = new ArrayList();

			foreach (FieldInfo fi in _enumType.GetFields())
			{
				ShortStringAttribute[] attrs = (ShortStringAttribute[])fi.GetCustomAttributes(typeof(ShortStringAttribute), false);
				if (attrs.Length > 0)
					values.Add(new DictionaryEntry(Convert.ChangeType(Enum.Parse(_enumType, fi.Name), underlyingType), attrs[0].Value));
			}
			return values;
		}

		public bool IsStringDefined(string stringValue)
		{
			return Parse(_enumType, stringValue) != null;
		}

		public bool IsStringDefined(string stringValue, bool ignoreCase)
		{
			return Parse(_enumType, stringValue, ignoreCase) != null;
		}

		public Type EnumType
		{
			get { return _enumType; }
		}
		#endregion

		#region Static Implementation
		public static string GetStringValue(Enum value)
		{
			string output = null;
			Type type = value.GetType();

			if (_stringValues.ContainsKey(value))
				output = (_stringValues[value] as ShortStringAttribute).Value;
			else
			{
				FieldInfo fi = type.GetField(value.ToString());
				ShortStringAttribute[] attrs =
					fi.GetCustomAttributes(typeof(ShortStringAttribute), false) as ShortStringAttribute[];

				if (attrs.Length > 0)
				{
					_stringValues.Add(value, attrs[0]);
					output = attrs[0].Value;
				}
			}

			return output;
		}

		public static object Parse(Type type, String stringValue)
		{
			return Parse(type, stringValue, false);
		}

		public static object Parse(Type type, string stringValue, bool ignoreCase)
		{
			object output = null;
			string enumStringValue = null;

			if (!type.IsEnum)
				throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}.", type.ToString()));

			foreach (FieldInfo fi in type.GetFields())
			{
				ShortStringAttribute[] attrs = (ShortStringAttribute[])fi.GetCustomAttributes(typeof(ShortStringAttribute), false);
				if (attrs.Length > 0)
					enumStringValue = attrs[0].Value;

				if (string.Compare(enumStringValue, stringValue, ignoreCase) == 0)
				{
					output = Enum.Parse(type, fi.Name);
					break;
				}
			}
			return output;
		}

		public static bool IsStringDefined(Type enumType, string stringValue)
		{
			return Parse(enumType, stringValue) != null;
		}

		public static bool IsStringDefined(Type enumType, string stringValue, bool ignoreCase)
		{
			return Parse(enumType, stringValue, ignoreCase) != null;
		}
		#endregion
	}

	public class StringEnum
	{
		#region Instance Implementation
		private Type _enumType;
		private static Dictionary<Enum, StringValueAttribute> _stringValues = new Dictionary<Enum,StringValueAttribute>();

		public StringEnum(Type enumType)
		{
			if (!enumType.IsEnum)
				throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}", enumType.ToString()));

			_enumType = enumType;
		}

		public string GetStringValue(string valueName)
		{
			Enum enumType;
			string stringValue = null;

			try
			{
				enumType = (Enum)Enum.Parse(_enumType, valueName);
				stringValue = GetStringValue(enumType);
			}
			catch (Exception) { }

			return stringValue;
		}

		public Array GetStringValues()
		{
			ArrayList values = new ArrayList();
			foreach (FieldInfo fi in _enumType.GetFields())
			{
				StringValueAttribute[] attrs = 
					(StringValueAttribute[])fi.GetCustomAttributes(typeof(StringValueAttribute), false);

				if (attrs.Length > 0)
					values.Add(attrs[0].Value);
			}

			return values.ToArray();
		}

		public IList GetListValues()
		{
			Type underlyingType = Enum.GetUnderlyingType(_enumType);
			ArrayList values = new ArrayList();

			foreach (FieldInfo fi in _enumType.GetFields())
			{
				StringValueAttribute[] attrs = (StringValueAttribute[])fi.GetCustomAttributes(typeof(StringValueAttribute), false);
				if(attrs.Length > 0)
					values.Add(new DictionaryEntry(Convert.ChangeType(Enum.Parse(_enumType, fi.Name), underlyingType), attrs[0].Value));
			}
			return values;
		}

		public bool IsStringDefined(string stringValue)
		{
			return Parse(_enumType, stringValue) != null;
		}

		public bool IsStringDefined(string stringValue, bool ignoreCase)
		{
			return Parse(_enumType, stringValue, ignoreCase) != null;
		}

		public Type EnumType
		{
			get { return _enumType; }
		}
		#endregion

		#region Static Implementation
		public static string GetStringValue(Enum value)
		{
			string output = null;
			Type type = value.GetType();

			if (_stringValues.ContainsKey(value))
				output = (_stringValues[value] as StringValueAttribute).Value;
			else
			{
				FieldInfo fi = type.GetField(value.ToString());
				StringValueAttribute[] attrs = 
					fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];

				if (attrs.Length > 0)
				{
					_stringValues.Add(value, attrs[0]);
					output = attrs[0].Value;
				}
			}

			return output;
		}

		public static object Parse(Type type, String stringValue)
		{
			return Parse(type, stringValue, false);
		}

		public static object Parse(Type type, string stringValue, bool ignoreCase)
		{
			object output = null;
			string enumStringValue = null;

			if(!type.IsEnum)
				throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}.", type.ToString()));

			foreach(FieldInfo fi in type.GetFields())
			{
				StringValueAttribute[] attrs = (StringValueAttribute[])fi.GetCustomAttributes(typeof(StringValueAttribute), false);
				if (attrs.Length > 0)
					enumStringValue = attrs[0].Value;

				if (string.Compare(enumStringValue, stringValue, ignoreCase) == 0)
				{
					output = Enum.Parse(type, fi.Name);
					break;
				}
			}
			return output;
		}

		public static bool IsStringDefined(Type enumType, string stringValue)
		{
			return Parse(enumType, stringValue) != null;
		}

		public static bool IsStringDefined(Type enumType, string stringValue, bool ignoreCase)
		{
			return Parse(enumType, stringValue, ignoreCase) != null;
		}
		#endregion		
	}

	enum PrintTagTypes
	{
		
		[StringValue("18 Up - Regular")]
		[ShortString("18UPREG")]
		REG18UP,
		[StringValue("32 Up - Regular")]
		[ShortString("32UPREG")]
		REG32UP,
		[StringValue("6 Up - Super Sale")]
		[ShortString("6UPSS")]
		SS6UP,
		[StringValue("12 Up - Super Sale")]
		[ShortString("12UPSS")]
		SS12UP,
		[StringValue("6 UP - Smart Buy")]
		[ShortString("6UPSB")]
		SB6UP,
		[StringValue("12 Up - Smart Buy")]
		[ShortString("12UPSB")]
		SB12UP,
		[StringValue("6 Up - Special Deal")]
		[ShortString("6UPSD")]
		SD6UP,
		[StringValue("12 Up - Special Deal")]
		[ShortString("12UPSD")]
		SD12UP,
		[StringValue("6 Up - Bonus Bucks")]
		[ShortString("6UPBB")]
		BB6UP,
		[StringValue("12 Up - Bonus Bucks")]
		[ShortString("12UPBB")]
		BB12UP,
		[StringValue("18 Up - Regular Discontinued")]
		[ShortString("18UPREGD")]
		REGD18UP,
		[StringValue("32 Up - Regular Discontinued")]
		[ShortString("32UPREGD")]
		REGD32UP,
		[StringValue("6 Up - Now Even Lower")]
		[ShortString("6UPNEL")]
		NEL6UP,
		[StringValue("12 Up - Now Even Lower")]
		[ShortString("12UPNEL")]
		NEL12UP,
		[StringValue("1 Up 14 x 11 Super Sale")]
		[ShortString("1UPXSS")]
		SS1UPX,
		[StringValue("1 Up 13 x 10 Super Sale")]
		[ShortString("1UPLSS")]
		SS1UPL,
		[StringValue("1 Up 11 x 8.5 Super Sale")]
		[ShortString("1UPMSS")]
		SS1UPM,
		[StringValue("1 Up 11 x 7 Super Sale")]
		[ShortString("1UPSSS")]
		SS1UPS,
		[StringValue("2 Up Super Sale")]
		[ShortString("2UPSS")]
		SS2UP,
		[StringValue("4 Up Super Sale")]
		[ShortString("4UPSS")]
		SS4UP,
		[StringValue("1 Up 14 x 11 Special Deal")]
		[ShortString("1UPXSD")]
		SD1UPX,
		[StringValue("1 Up 13 x 10 Special Deal")]
		[ShortString("1UPLSD")]
		SD1UPL,
		[StringValue("1 Up 11 x 8.5 Special Deal")]
		[ShortString("1UPMSD")]
		SD1UPM,
		[StringValue("1 Up 11 x 7 Special Deal")]
		[ShortString("1UPSSD")]
		SD1UPS,
		[StringValue("2 Up Special Deal")]
		[ShortString("2UPSD")]
		SD2UP,
		[StringValue("4 Up Special Deal")]
		[ShortString("4UPSD")]
		SD4UP,
		[StringValue("1 Up 14 x 11 Smart Buy")]
		[ShortString("1UPXSB")]
		SB1UPX,
		[StringValue("1 Up 13 x 10 Smart Buy")]
		[ShortString("1UPLSB")]
		SB1UPL,
		[StringValue("1 Up 11 x 8.5 Smart Buy")]
		[ShortString("1UPMSB")]
		SB1UPM,
		[StringValue("1 Up 11 x 7 Smart Buy")]
		[ShortString("1UPSSB")]
		SB1UPS,
		[StringValue("2 Up Smart Buy")]
		[ShortString("2UPSB")]
		SB2UP,
		[StringValue("4 Up Smart Buy")]
		[ShortString("4UPSB")]
		SB4UP
	}
}
